/**
 * @author qiushaohua 2012-5-27
 */
package com.feizhi.common.download.controller;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.NativeWebRequest;

import com.feizhi.common.upload.UploadFileUtil;

/**
 * 文件下载
 *
 * @author shuaqiu 2013年12月16日
 *
 */
@Controller
@RequestMapping(value = "/download")
public class DownloadController {

    private static final Log log = LogFactory.getLog(DownloadController.class);

    /**
     * Download file.
     * 
     * @param req
     * @param userAgent
     *            the browser agent code
     * @param name
     *            file name
     * @param uri
     *            file real path
     * @return file resource
     */
    @RequestMapping(value = "/{name}", method = { RequestMethod.GET,
            RequestMethod.POST })
    public HttpEntity<Resource> download(final NativeWebRequest req,
            @RequestHeader(value = "User-Agent") final String userAgent,
            @PathVariable(value = "name") final String name,
            @RequestParam(value = "uri") final String uri) {
        final File file = UploadFileUtil.getFile(req, uri);
        if (file == null) {
            return new ResponseEntity<Resource>(HttpStatus.NOT_FOUND);
        }

        final HttpHeaders headers = new HttpHeaders();
        final String encodedName = encodeName(name, userAgent);
        headers.set("Content-Disposition", "attachment; filename=\""
                + encodedName + "\"");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new HttpEntity<Resource>(new FileSystemResource(file), headers);
    }

    /**
     * handle the name encoding.
     *
     * @param name
     *            the file name
     * @param userAgent
     *            the browser agent code
     * @return maybe correct encoded file name.
     * @throws UnsupportedEncodingException
     */
    private String encodeName(final String name, final String userAgent) {
        try {
            String encodedName;
            if (userAgent != null && userAgent.indexOf("MSIE") >= 0) {
                encodedName = URLEncoder.encode(name, "UTF-8");
                log.debug("ie --> " + encodedName);
            } else {
                encodedName = new String(name.getBytes("UTF-8"), "ISO8859-1");
                log.debug("other browser --> " + encodedName);
            }
            return encodedName;
        } catch (final UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        }
        return name;
    }

}
